/**
 * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 */

package com.mpower.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BasicDynaClass;
import org.apache.commons.beanutils.DynaBean;
import org.apache.commons.beanutils.DynaClass;
import org.apache.commons.beanutils.DynaProperty;

import com.liferay.counter.service.CounterLocalServiceUtil;
import com.liferay.portal.kernel.dao.orm.QueryUtil;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portlet.expando.NoSuchTableException;
import com.liferay.portlet.expando.model.ExpandoColumn;
import com.liferay.portlet.expando.model.ExpandoRow;
import com.liferay.portlet.expando.model.ExpandoTable;
import com.liferay.portlet.expando.model.ExpandoValue;
import com.liferay.portlet.expando.service.ExpandoColumnLocalServiceUtil;
import com.liferay.portlet.expando.service.ExpandoRowLocalServiceUtil;
import com.liferay.portlet.expando.service.ExpandoTableLocalServiceUtil;
import com.liferay.portlet.expando.service.ExpandoValueLocalServiceUtil;
import com.mpower.service.base.DynaTableLocalServiceBaseImpl;

/**
 * The implementation of the dyna table local service.
 *
 * <p>
 * All custom service methods should be put in this class. Whenever methods are added, rerun ServiceBuilder to copy their definitions into the {@link com.mpower.service.DynaTableLocalService} interface.
 * </p>
 *
 * <p>
 * Never reference this interface directly. Always use {@link com.mpower.service.DynaTableLocalServiceUtil} to access the dyna table local service.
 * </p>
 *
 * <p>
 * This is a local service. Methods of this service will not have security checks based on the propagated JAAS credentials because this service can only be accessed from within the same VM.
 * </p>
 *
 * @author Arun
 * @see com.mpower.service.base.DynaTableLocalServiceBaseImpl
 * @see com.mpower.service.DynaTableLocalServiceUtil
 */
public class DynaTableLocalServiceImpl extends DynaTableLocalServiceBaseImpl {
	
	public ExpandoTable addTable(long companyId, String tableName) throws PortalException, SystemException{
		
		try {
			ExpandoTableLocalServiceUtil.deleteTable(
				companyId, DynaTableLocalServiceImpl.class.getName(), tableName);
		}
		catch (NoSuchTableException nste) {}
		
		return ExpandoTableLocalServiceUtil.addTable(
				companyId, DynaTableLocalServiceImpl.class.getName(), tableName);
	}
	
	public ExpandoColumn addColumn(long tableId, String name, int type) throws PortalException, SystemException{
		
		return ExpandoColumnLocalServiceUtil.addColumn(
				tableId, name, type);
	}
	
	public int getTableRowsCount(long companyId, String tableName)throws SystemException {

		return ExpandoRowLocalServiceUtil.getRowsCount(
			companyId, DynaTableLocalServiceImpl.class.getName(), tableName);
	}
	
	public List<ExpandoRow> getRows(long companyId, String tableName){
		List<ExpandoRow> expandoRows = null;
		try {
			expandoRows = ExpandoRowLocalServiceUtil.getRows(
					companyId, DynaTableLocalServiceImpl.class.getName(),
					tableName, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
		} catch (SystemException e) {
			expandoRows = new ArrayList<ExpandoRow>();
		}
		return expandoRows;
	}
	
	public String getData(long companyId, String tableName, String columnName, String classPK) throws PortalException, SystemException{
		return ExpandoValueLocalServiceUtil.getData(companyId, DynaTableLocalServiceImpl.class.getName(), 
				tableName, columnName, Long.parseLong(classPK), "");
	}
	
	public List<ExpandoColumn> getColumns(long companyId, String tableName){
		List<ExpandoColumn> expandoColumns = null;
		try {
			expandoColumns = ExpandoColumnLocalServiceUtil.getColumns(companyId,
					DynaTableLocalServiceImpl.class.getName(), tableName);
		} catch (SystemException e) {
			return new ArrayList<ExpandoColumn>();
		}
		return expandoColumns;
	}
	
	public List<ExpandoValue> addValue(long companyId, String tableName, Map<String,String> fieldsMap) throws SystemException, PortalException{
		
		long classPK = CounterLocalServiceUtil.increment(
				DynaTableLocalServiceImpl.class.getName());
		List<ExpandoValue> expandoValues = new ArrayList<ExpandoValue>();
		for (String columnName : fieldsMap.keySet()) {
			String fieldValue = fieldsMap.get(columnName);

			expandoValues.add(
			ExpandoValueLocalServiceUtil.addValue(
					companyId, DynaTableLocalServiceImpl.class.getName(), tableName,
					columnName, classPK, fieldValue));
		}
		return expandoValues;
	}

	public List<DynaBean> getDynaList(long companyId, String tableName) throws PortalException, SystemException{
		
		List<String> headerNames = new ArrayList<String>();
		List<ExpandoColumn> expandoColumns = getColumns(companyId, tableName);
		HashMap<String, String[]> hm = getColumnNames(expandoColumns);
		 
		DynaProperty[] props = new DynaProperty[hm.size() + 1];
		int count=0;
		Iterator<String> itr = hm.keySet().iterator();
		while (itr.hasNext()) {
			String key = (String) itr.next();
			String[] obj = hm.get(key);
		    props[count] = new DynaProperty(obj[0], String.class);
		    headerNames.add(obj[0]);
		    count++;
		}
		props[count] = new DynaProperty("classPK", String.class);
		
	    List<ExpandoRow> rows = getRows(companyId, tableName);
	    DynaClass dynaClass = new BasicDynaClass("DynaClass", null, props);	
		
	    List<DynaBean> dynaBeans = new ArrayList<DynaBean>();
	    
	    for (ExpandoRow er : rows){
	        DynaBean db = null;
			try {
				db = dynaClass.newInstance();
		        String classPK = String.valueOf(er.getClassPK());
		        db.set("classPK", classPK);	
		        for (String headerName : headerNames){
			         String data = getData(companyId, tableName, headerName, classPK);
			         db.set(headerName, data);		        	
		        }
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InstantiationException e) {
				e.printStackTrace();
			}
			dynaBeans.add(db);	    	
	    }
	return dynaBeans;
	}
	
	public List<Object> getRow(long companyId, String tableName, long classPK) throws PortalException, SystemException{
		List<Object> result = new ArrayList<Object>();
		List<ExpandoColumn> expandoColumns = getColumns(companyId, tableName);
		HashMap<String, String[]> hm = getColumnNames(expandoColumns);
		List<String> headerNames = new ArrayList<String>();
		DynaProperty[] props = new DynaProperty[hm.size() + 1];
		int count=0;
		Iterator<String> itr = hm.keySet().iterator();
		while (itr.hasNext()) {
			String key = (String) itr.next();
			String[] obj = hm.get(key);
		    props[count] = new DynaProperty(obj[0], String.class);
		    headerNames.add(obj[0]);
		    count++;
		}
		props[count] = new DynaProperty("classPK", String.class);	
		DynaClass dynaClass = new BasicDynaClass("DynaClass", null, props);
		result.add(0, headerNames);
		DynaBean db = null;
		try {
			db = dynaClass.newInstance();
	        db.set("classPK", String.valueOf(classPK));	
	        for (String headerName : headerNames){
		         String data = getData(companyId, tableName, headerName, String.valueOf(classPK));
		         db.set(headerName, data);		        	
	        }
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		}
		result.add(1, db);
		return result;
	}

	private HashMap<String, String[]> getColumnNames(List<ExpandoColumn> expandoColumns) {
		HashMap<String, String[]> hm = new HashMap<String, String[]>(); 
		for (ExpandoColumn ec : expandoColumns) {
			String[] expandoColumnArray = {ec.getName(), String.valueOf(ec.getType())};
			hm.put(String.valueOf(ec.getColumnId()),expandoColumnArray);
		}
		return hm;
	}	
	
	public List<String> getDynaPropertys(DynaBean dynaBean){
		DynaClass dynaClass = dynaBean.getDynaClass();
		DynaProperty[] prop = dynaClass.getDynaProperties();
		List<String> colNames = new ArrayList<String>();
		for (DynaProperty property : prop){
			if("classPK".equalsIgnoreCase(property.getName()))continue;
			colNames.add(property.getName());
		}
		return colNames;
	}
	
   	
}